home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl1 / examples / porting / xsolar_opengl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  11.2 KB  |  417 lines

  1. /*
  2.  * Copyright 1993, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*                xsolar_opengl.c
  18.  *    Displays a planet with a moon, orbiting a sun.
  19.  *     Uses X and Open GL widget.
  20.  *
  21.  *    Exit with the ESCape key or through the window manager menu.
  22.  */
  23. #include <Xm/Xm.h>
  24. #include <Xm/Frame.h>
  25. #include <Xm/Form.h>
  26. #include <X11/StringDefs.h>
  27. #include <X11/keysym.h>
  28.  
  29. #include <GL/GLwMDrawA.h>
  30. #include <GL/gl.h>
  31. #include <GL/glu.h>
  32. #include <GL/glx.h>
  33. #include <stdio.h>
  34. #include <math.h>
  35.  
  36. typedef struct _spin {
  37.     GLfloat year;
  38. } SPINDATA, *SPINPTR;
  39.  
  40. /* function prototypes */
  41.  
  42. void main(int argc, char **argv);
  43.  
  44. void initCB (Widget w, XtPointer client_data, XtPointer call_data);
  45. void exposeCB (Widget w, XtPointer spin, XtPointer call_data);
  46. void resizeCB (Widget w, XtPointer spin, XtPointer call_data);
  47. void inputCB (Widget w, XtPointer client_data, XtPointer call_data);
  48.  
  49. GLboolean drawWP (XtPointer spin);
  50.  
  51. void drawscene(SPINPTR spin);
  52. void setbeachball(int stripes);
  53. void beachball(unsigned long color1, unsigned long color2);
  54.  
  55. SPINPTR spin;
  56.  
  57. static XtAppContext app_context;
  58. static XtWorkProcId workprocid = NULL;
  59.  
  60. GLXContext    glx_context;
  61. Display     *global_display;
  62. Window         global_window;
  63.  
  64. /* Create application context, and a form widget to contain
  65.  * the Open GL widget.  Set up the Open GL widget callbacks
  66.  */
  67. void main(int argc, char **argv)
  68. {
  69.     Arg wargs[15];
  70.     int n;
  71.     Widget glw, toplevel, frame, form;
  72.  
  73.     static String fallback_resources[] = {
  74.         "*frame*shadowType: SHADOW_IN",
  75.         "*glwidget*width: 750",
  76.         "*glwidget*height: 600",
  77.         "*glwidget*rgba: TRUE",
  78.         "*glwidget*doublebuffer: TRUE",
  79.         "*glwidget*allocateBackground: TRUE",
  80.         NULL
  81.     };
  82.  
  83.     /*    create main data structure, spin pointer    */
  84.     spin = (SPINPTR) malloc (sizeof (SPINDATA));
  85.     spin->year = 0.0;
  86.  
  87.     toplevel = XtAppInitialize(
  88.             &app_context,    /* Application context */
  89.             "XSolar",    /* Application class */
  90.             NULL, 0,     /* command line option list */
  91.             &argc, argv,    /* command line args */
  92.             fallback_resources,
  93.             NULL,        /*  argument list  */
  94.             0);        /* number of arguments */
  95.  
  96.     n = 0;
  97.     form = XmCreateForm(toplevel, "form", wargs, n);
  98.     XtManageChild(form);
  99.  
  100.     n = 0;
  101.     XtSetArg(wargs[n], XtNx, 30); n++;
  102.     XtSetArg(wargs[n], XtNy, 30); n++;
  103.     XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  104.     XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  105.     XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  106.     XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  107.  
  108.     XtSetArg(wargs[n], XmNleftOffset, 30); n++;
  109.     XtSetArg(wargs[n], XmNbottomOffset, 30); n++;
  110.     XtSetArg(wargs[n], XmNrightOffset, 30); n++;
  111.     XtSetArg(wargs[n], XmNtopOffset, 30); n++;
  112.     frame = XmCreateFrame (form, "frame", wargs, n);
  113.     XtManageChild (frame);
  114.  
  115.     n = 0;
  116.     glw = GLwCreateMDrawingArea(frame, "glwidget", wargs, n);
  117.     XtManageChild (glw);
  118.     XtAddCallback(glw, GLwNginitCallback, initCB, 
  119.         (XtPointer) NULL);
  120.     XtAddCallback(glw, GLwNexposeCallback, exposeCB, 
  121.         (XtPointer) spin);
  122.     XtAddCallback(glw, GLwNresizeCallback, resizeCB, 
  123.         (XtPointer) spin);
  124.     XtAddCallback(glw, GLwNinputCallback, inputCB, 
  125.         (XtPointer) NULL);
  126.  
  127.     XtRealizeWidget(toplevel);    /* instantiate it now */
  128.     XtAppMainLoop(app_context);    /* loop for events */
  129. }    /*   end main()   */
  130.  
  131. /*        initCB     
  132.  *    The initCB subroutine initializes graphics modes and
  133.  *    transformation matrices.
  134.  */
  135.  
  136. void initCB (Widget w, XtPointer client_data, XtPointer call_data)
  137. {
  138.     Arg args[1];
  139.     XVisualInfo *vi;
  140.  
  141.     XtSetArg(args[0], GLwNvisualInfo, &vi);
  142.     XtGetValues(w, args, 1);
  143.  
  144.     global_display = XtDisplay(w);
  145.     global_window = XtWindow(w);
  146.     glx_context = glXCreateContext(global_display, vi, 0, GL_FALSE);
  147. }    /*   end initCB()   */
  148.  
  149. /*    exposeCB() and resizeCB() are called when the window
  150.  *    is uncovered, moved, or resized.
  151.  */
  152.  
  153. void exposeCB (Widget w, XtPointer ptr, XtPointer call_data)
  154. {
  155.     SPINPTR spin = (SPINPTR) ptr;
  156.     static int first_time = 1;
  157.     GLwDrawingAreaCallbackStruct *call_ptr = 
  158.         (GLwDrawingAreaCallbackStruct *) call_data;
  159.  
  160.     GLwDrawingAreaMakeCurrent(w, glx_context);
  161.  
  162.     if (first_time) {
  163.         glClearColor(0.0, 0.0, 0.0, 0.0);   
  164.  
  165.         glShadeModel(GL_FLAT);
  166.         glEnable(GL_DEPTH_TEST);
  167.  
  168.         glMatrixMode(GL_PROJECTION);
  169.         glLoadIdentity();
  170.         gluPerspective(45.0, (GLfloat)(call_ptr->width)
  171.                 /(GLfloat)(call_ptr->height), 1.0, 25.0);
  172.         glMatrixMode(GL_MODELVIEW);
  173.         glLoadIdentity();
  174.         glTranslatef(0.0, 0.0, -12.0);
  175.  
  176.         workprocid = XtAppAddWorkProc 
  177.             (app_context, drawWP, spin);    /*  ptr is spin  */
  178.         first_time = 0;
  179.     }
  180.     drawscene(spin);
  181. }
  182.  
  183. void resizeCB (Widget w, XtPointer ptr, XtPointer call_data)
  184. {
  185.     SPINPTR spin = (SPINPTR) ptr;
  186.     GLwDrawingAreaCallbackStruct *call_ptr = 
  187.         (GLwDrawingAreaCallbackStruct *) call_data;
  188.  
  189.     GLwDrawingAreaMakeCurrent(w, glx_context);
  190.  
  191.     glViewport(0, 0, (GLsizei) (call_ptr->width-1),
  192.             (GLsizei) (call_ptr->height-1));
  193.  
  194.     glMatrixMode(GL_PROJECTION);
  195.     glLoadIdentity();
  196.     gluPerspective(45.0, (GLfloat)(call_ptr->width)
  197.             /(GLfloat)(call_ptr->height), 1.0, 25.0);
  198.     glMatrixMode(GL_MODELVIEW);
  199.     glLoadIdentity ();
  200.     glTranslatef(0.0, 0.0, -12.0);
  201.  
  202.     drawscene(spin);
  203. }
  204.  
  205. /*    inputCB() handles all types of input from the GL widget.
  206.  *    The KeyRelease handles the ESCape key, so that it exits
  207.  *    the program.  
  208.  */
  209. void inputCB (Widget w, XtPointer client_data, 
  210.     XtPointer call_data)
  211. {
  212.     char buffer[1];
  213.     KeySym keysym;
  214.     GLwDrawingAreaCallbackStruct *call_ptr = 
  215.         (GLwDrawingAreaCallbackStruct *) call_data;
  216.     XKeyEvent *kevent = (XKeyEvent *) (call_ptr->event);
  217.  
  218.     GLwDrawingAreaMakeCurrent(w, glx_context);
  219.  
  220.     switch(call_ptr->event->type) {
  221.     case KeyRelease:
  222.         /* It is necessary to convert the keycode to a 
  223.          * keysym before checking if it is an escape */
  224.         if (XLookupString(kevent,buffer,1,&keysym,NULL) == 1 
  225.             && keysym == (KeySym)XK_Escape)
  226.             exit(0);
  227.         break;
  228.     default:
  229.         break;
  230.     }
  231. }
  232.  
  233. /*    drawWP() is called by the WorkProc.  When the scene
  234.  *    is in automatic motion, the WorkProc calls this routine,
  235.  *    which adds 1 degree (10 tenths) to the cumulative amount
  236.  *    of rotation.  drawscene() is called, so the image is
  237.  *    redrawn.  It returns(FALSE) so the WorkProc does not
  238.  *    discontinue operation.
  239.  */
  240. GLboolean drawWP (XtPointer ptr)
  241. {
  242.     SPINPTR spin;
  243.  
  244.     spin = (SPINPTR) ptr;
  245.     spin->year = fmodf((spin->year + 1.0), 360.0);
  246.     drawscene (spin);
  247.     return (FALSE);
  248. }
  249.  
  250.  
  251. /*    drawscene calculates angles relative to the spin->year
  252.  *    and then draws sun, planet, and moon.
  253.  */
  254.  
  255. void drawscene(SPINPTR spin)
  256. {
  257.     static GLfloat bluecol[] = { 0, 0, 1.0 };
  258.     static GLfloat whitecol[] = { 1.0, 1.0, 1.0 };
  259.     GLfloat sunangle, dayangle, monthangle;
  260.     /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
  261.     GLfloat earthdist = 4.5, earthscale = 0.5;
  262.     GLfloat moondist = 0.9, moonscale = 0.2;
  263.  
  264.     glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  265.  
  266.     glPushMatrix();
  267.         glRotatef(10.0, 1.0, 0.0, 0.0); /*  tilt scene slightly    */
  268.         glPushMatrix(); 
  269.             sunangle = fmodf((spin->year*365.0/25.0), 360.0);
  270.             /* sun rotates on axis every 25 days */
  271.                 glRotatef(sunangle, 0.0, 1.0, 0.0);
  272.                 /* cpack format color1, color2 swapped by hand */
  273.             /* was beachball(0x20C0FF, 0x200FFFF);  */
  274.             beachball(0xFFC02000, 0xFFFF0020);
  275.         glPopMatrix();
  276.         glPushMatrix();
  277.             glRotatef(spin->year, 0.0, 1.0, 0.0);
  278.             glTranslatef(earthdist,  0.0,  0.0);
  279.             glPushMatrix();
  280.                 dayangle = fmodf((spin->year*5.0), 360.0);    
  281.                 /* dayangle fudged so earth rotation shows  */
  282.                 glRotatef(dayangle, 0.0, 1.0, 0.0);
  283.                 glScalef(earthscale,  earthscale,  earthscale);
  284.                 glColor3fv(bluecol);
  285.                 /* swapped; was beachball(0xFF0000, 0xC02000);*/
  286.                 beachball(0x0000FF00, 0x0020C000); /* earth */
  287.             glPopMatrix();
  288.             monthangle = fmodf((spin->year*365.0/28.0), 360.0);
  289.             glRotatef(monthangle, 0.0, 1.0, 0.0);
  290.             glTranslatef(moondist,  0.0,  0.0);
  291.             glScalef(moonscale,  moonscale,  moonscale);
  292.             glColor3fv(whitecol);
  293.             /* hand swapped; was beachball(0xFFFFFF, 0xC0C0C0); */
  294.             beachball(0xFFFFFF00, 0xC0C0C000); /* moon */
  295.         glPopMatrix();
  296.     glPopMatrix();
  297.  
  298.     glXSwapBuffers(global_display, global_window);
  299. }   /*  end drawscene()  */
  300.  
  301. /* BEACHBALL */
  302.  
  303. /* three dimensional vector */
  304. typedef float vector[3];
  305.  
  306. static vector front  = { 0.0,  0.0,  1.0 };
  307. static vector back   = { 0.0,  0.0, -1.0 };
  308. static vector top    = { 0.0,  1.0,  0.0 };
  309. static vector bottom = { 0.0, -1.0,  0.0 };
  310. static vector right  = { 1.0,  0.0,  0.0 };
  311. static vector left   = { -1.0,  0.0,  0.0 };
  312. static vector center = { 0.0,  0.0,  0.0 };
  313.  
  314. /* Number of colored stripes. Should be even to look right */
  315. #define BEACHBALL_STRIPES 12
  316.  
  317. /* Default number of polygons  making up a stripe. Should be even */
  318. #define BEACHBALL_POLYS 16
  319.  
  320. /* array of vertices making up a stripe */
  321. static vector stripe_point[BEACHBALL_POLYS + 3];
  322.  
  323. /* has the beachball been initialized */
  324. static GLboolean beachball_initialized = FALSE;
  325.  
  326. /* Number of polygons making up a stripe */
  327. static int beachball_stripes;
  328.  
  329. /* Number of vertices making up a stripe */
  330. static int stripe_vertices;
  331.  
  332. /* Initialize beachball_point array to be a stripe 
  333.  * of unit radius.
  334.  */
  335. void setbeachball(int stripes)
  336. {
  337.     int i,j;
  338.     float x,y,z;             /* vertex points */
  339.     float theta,delta_theta;    /* angle from top pole to bottom pole */
  340.     float offset;         /* offset from center of stripe to vertex */
  341.     float cross_radius; /* radius of cross section at current latitude */
  342.     float cross_theta;  /* angle occupied by a stripe  */
  343.  
  344.     beachball_stripes = stripes;
  345.  
  346.     /* polys distributed by even angles from top to bottom */
  347.     delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
  348.     theta = delta_theta;
  349.  
  350.     cross_theta = 2.0*M_PI/(float)beachball_stripes;
  351.  
  352.     j = 0;
  353.  
  354.     stripe_point[j][0] = top[0];
  355.     stripe_point[j][1] = top[1];
  356.     stripe_point[j][2] = top[2];
  357.     j++;
  358.  
  359.     for (i = 0; i < BEACHBALL_POLYS; i += 2) {
  360.         cross_radius = fsin(theta);
  361.         offset = cross_radius * ftan(cross_theta/2.0);
  362.  
  363.         stripe_point[j][0] = - offset;
  364.         stripe_point[j][1] = fcos(theta);
  365.         stripe_point[j][2] = cross_radius;
  366.         j++;
  367.  
  368.         stripe_point[j][0] = offset;
  369.         stripe_point[j][1] = stripe_point[j-1][1];
  370.         stripe_point[j][2] = stripe_point[j-1][2];
  371.         j++;
  372.  
  373.         theta += delta_theta;
  374.     }
  375.  
  376.     stripe_point[j][0] = bottom[0];
  377.     stripe_point[j][1] = bottom[1];
  378.     stripe_point[j][2] = bottom[2];
  379.  
  380.     stripe_vertices = j + 1;
  381.  
  382.     beachball_initialized = TRUE;
  383. }
  384.  
  385. /*
  386.  *    Draws a canonical beachball.  The colors are cpack values.
  387.  */
  388. void beachball(unsigned long c1, unsigned long c2)
  389. {
  390.     GLfloat angle, delta_angle;
  391.     int i,j;
  392.  
  393.     if (! beachball_initialized)
  394.         setbeachball(BEACHBALL_STRIPES);
  395.  
  396.     angle = 0.0;
  397.     delta_angle = 360.0/(float)beachball_stripes;
  398.  
  399.     for (i = 0; i < beachball_stripes; i++) {
  400.         if ( i%2 == 0)
  401.             glColor4ubv((GLubyte *)(&c1));
  402.         else glColor4ubv((GLubyte *)(&c2));
  403.  
  404.         glPushMatrix();
  405.             glRotatef(angle, 0.0, 1.0, 0.0);
  406.  
  407.             angle += delta_angle;
  408.  
  409.             glBegin(GL_TRIANGLE_STRIP);
  410.                 for (j = 0; j < stripe_vertices; j++)
  411.                     glVertex3fv(stripe_point[j]);
  412.             glEnd();
  413.         glPopMatrix();
  414.     }
  415. }
  416.  
  417.